﻿using System.Collections.Concurrent;
using System.Text;
using System.Text.RegularExpressions;

namespace ContentHolder
{
    public sealed class CombinKeywordRegexMatcher : IKeywordMatcher
    {
        private readonly string[] _patterns;

        public CombinKeywordRegexMatcher(IEnumerable<string> keywords)
        {
            _patterns = this.GetPatterns(keywords).ToArray();
        }

        private IEnumerable<string> GetPatterns(IEnumerable<string> keywords)
        {

            foreach (var item in keywords.Where(k => k.Contains('*')))
            {
                var items = item.Split('*');
                var patternStr = new StringBuilder();
                for (int i = 0; i < items.Length; i++)
                {
                    var part = items[i];
                    if (string.IsNullOrEmpty(part))
                    {
                        patternStr.Append(".{0,10}");
                    }
                    else
                    {
                        patternStr.Append(part);
                        if (i < items.Length - 1)
                        {
                            patternStr.Append(".{0,10}");
                        }
                    }
                }
                yield return patternStr.ToString();
            }
        }

        public IEnumerable<string> Matching(string source)
        {
            var result = new ConcurrentBag<string>();
            Parallel.ForEach(this._patterns, (pattern, i) =>
            {
                try
                {
                    foreach (Match item in Regex.Matches(source, pattern))
                    {
                        result.Add(item.Value);
                    }
                }
                catch
                {
                }
            });

            return result;
        }
    }
}
